package units;

import pheromoneMap.PheromoneMap;
import pheromoneMap.PheromoneType;
import base.PheromoneMain;
import base.ProxyBot;
import base.WargusUnit;
import base.UnitType;
import units.AntUnit;
import java.util.*;

public class WorkerUnit extends AntUnit {

	long previous_food_count;
	long current_food_count;

	protected WorkerUnitState previous_state;
	public WorkerUnitState m_state;

	private final double GO_AWAY_LIMIT = 0.8;
	private int previous_state_int;
	
	public WorkerUnit(ProxyBot proxyBot, PheromoneMap pheromoneMap,
			WargusUnit wargusUnit) {
		super(proxyBot, pheromoneMap, wargusUnit);

		previous_food_count = 1;
		this.m_state = WorkerUnitState.IDLE;
		this.previous_state = WorkerUnitState.IDLE;
	}

	public void setFoodCount(long count) {
		current_food_count = count;
	}

	public String getState() {
		return m_state.getName();
	}

	public void updateState() {
		super.updateState();
		// System.out.println( "Current state is " + unit.getUnitStatus() );
		double heading2 = unit.getHeading();

		int xPos = unit.getLocX();
		int yPos = unit.getLocY();

		int x2 = (int) (1 * Math.round(Math.cos(heading2)));
		int y2 = (int) (1 * Math.round(Math.sin(heading2)));

		int map_x = unit.getLocX() + x2;
		int map_y = unit.getLocY() + y2;

		this.current_food_count = this.proxyBot.getFood();

		if (pheromoneMap.getMagnitude(unit.getLocX(), unit.getLocY(),
				PheromoneType.DEATH) > DEATH_THRESHOLD) {
			this.previous_state = m_state;
			m_state = WorkerUnitState.FLEE;

		}
		else if (pheromoneMap.getMagnitude(unit.getLocX(), unit.getLocY(),
				PheromoneType.DEATH) < DEATH_THRESHOLD
				&& m_state == WorkerUnitState.FLEE)
		{
			m_state = previous_state;
		}
		else if (unit.getStatus()[0] == 0 && this.previous_state_int == 3
				&& (m_state == WorkerUnitState.BUILD_FARM
					|| m_state == WorkerUnitState.BUILD_BARRACKS
					|| m_state == WorkerUnitState.BUILD_BLACKSMITH
					|| m_state == WorkerUnitState.BUILD_LUMBERMILL
					|| m_state == WorkerUnitState.BUILD_TOWER)) {

			m_state = WorkerUnitState.IDLE;

		} else if (m_state == WorkerUnitState.STOP && unit.getRAmount() < 100) {

			if (proxyBot.GetMapCell(unit.getLocY(), unit.getLocX()) != 'B'){//!(proxyBot.checkAdjacentUnit(xPos, yPos,
					//UnitType.HUMAN_ELVEN_LUMBER_MILL))
					//&& !(proxyBot.checkAdjacentUnit(xPos, yPos,
							//UnitType.GOLDMINE))
					//&& !(proxyBot.checkAdjacentUnit(xPos, yPos,
							//UnitType.HUMAN_TOWN_HALL))) {
				proxyBot.stop(unit.getUnitID());
				m_state = WorkerUnitState.IDLE;
			}
		} else if (m_state == WorkerUnitState.IDLE && unit.getStatus()[0] == 0) {
			this.buildState();
		} 
		else if (m_state == WorkerUnitState.RETURNING_RESOURCES 
				&& unit.getRAmount() < 100 
				&& proxyBot.GetMapCell(unit.getLocY(), unit.getLocX()) != 'B') {
			
				m_state = WorkerUnitState.IDLE;
			
		}
		else if (unit.getRAmount() == 100
				&& (m_state == WorkerUnitState.HARVEST_GOLD || m_state == WorkerUnitState.HARVEST_WOOD)) {

			if (proxyBot.GetMapCell(unit.getLocY(), unit.getLocX()) != 'B'){//!(proxyBot.checkAdjacentUnit(xPos, yPos,
					//UnitType.HUMAN_ELVEN_LUMBER_MILL))
					//&& !(proxyBot.checkAdjacentUnit(xPos, yPos,
							//UnitType.GOLDMINE))
					//&& !(proxyBot.checkAdjacentUnit(xPos, yPos,
							//UnitType.HUMAN_TOWN_HALL))) {
				proxyBot.stop(unit.getUnitID());

				if (m_state == WorkerUnitState.HARVEST_GOLD)
					m_state = WorkerUnitState.RETURNING_WITH_GOLD;
				else
					m_state = WorkerUnitState.RETURNING_WITH_WOOD;
			} //else
				//m_state = WorkerUnitState.STOP;

		} else if (m_state == WorkerUnitState.FIND_WOOD) {
			if (proxyBot.checkAdjacentTerrainType(xPos, yPos, 'T')) {

				m_state = WorkerUnitState.HARVEST_WOOD;
				proxyBot.harvest(unit.getUnitID(), 2);
			}
		} else if (m_state == WorkerUnitState.FIND_GOLD) {

			if (proxyBot.checkAdjacentUnit(xPos, yPos, UnitType.GOLDMINE)) {

				m_state = WorkerUnitState.HARVEST_GOLD;
				proxyBot.harvest(unit.getUnitID(), 1);
			}
		} else if ((m_state == WorkerUnitState.RETURNING_WITH_WOOD || m_state == WorkerUnitState.RETURNING_WITH_GOLD)
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {
			if (proxyBot.checkAdjacentUnit(xPos, yPos, UnitType.HUMAN_TOWN_HALL)) {
				m_state = WorkerUnitState.RETURNING_RESOURCES;
				proxyBot.returnWithResource(unit.getUnitID());
			}

			else if (unit.getRAmount() < 100) {
				m_state = WorkerUnitState.IDLE;
				
				if (proxyBot.GetMapCell(unit.getLocY(), unit.getLocX()) != 'B'){
					proxyBot.stop(unit.getUnitID());
				}
			}

		}

	}

	public void move() {
		double heading2 = unit.getHeading();
		this.pheromoneMap.placeAttractionPheromone(this.unit.getLocX(),
				this.unit.getLocY(), PheromoneType.MY_TERRITORY, 5.0);
		if (m_state == WorkerUnitState.FLEE) {
			moveTrail(PheromoneType.TO_HOME, PheromoneType.ENEMY);//moveTrail(PheromoneType.TO_HOME);
		} else if ((m_state == WorkerUnitState.RETURNING_WITH_WOOD || m_state == WorkerUnitState.RETURNING_WITH_GOLD)
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {
			// Check to see if there's any pheromone trail and follow it
			// if (pheromoneMap.getMagnitude(unit.getLocX(), unit.getLocY(),
			// PheromoneType.TO_HOME) >= 0.01) {
			// moveTrail(PheromoneType.TO_HOME);
			// // Else, move randomly
			// } else {
			// moveRandom();
			// }
			moveTrail(PheromoneType.TO_HOME, PheromoneType.ENEMY);

			// System.out.println(previous_state);

			if (m_state == WorkerUnitState.RETURNING_WITH_GOLD) {
				layPheromone(PheromoneType.TO_GOLD, 100, Math.PI + heading2);
			}

			else if (m_state == WorkerUnitState.RETURNING_WITH_WOOD) {
				layPheromone(PheromoneType.TO_WOOD, 100, Math.PI + heading2);
			}

			// System.out.println(unit.getStatus());
			// layPheromone( PheromoneType.TO_WOOD, 1, Math.PI + heading2 );
		} else if (m_state == WorkerUnitState.FIND_WOOD
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {

			moveTrail(PheromoneType.TO_WOOD, PheromoneType.ENEMY);//moveTrail(PheromoneType.TO_WOOD);

			layPheromone(PheromoneType.TO_HOME, 100, Math.PI + heading2);
		}

		else if (m_state == WorkerUnitState.FIND_GOLD
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {

			moveTrail(PheromoneType.TO_GOLD, PheromoneType.ENEMY);//moveTrail(PheromoneType.TO_GOLD);
			layPheromone(PheromoneType.TO_HOME, 100, Math.PI + heading2);
		}

		else if (m_state == WorkerUnitState.BUILD_FARM
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {

			this.buildBuilding(UnitType.HUMAN_FARM);
		}

		else if (m_state == WorkerUnitState.BUILD_BARRACKS
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {

			this.buildBuilding(UnitType.HUMAN_BARRACKS);
		}

		else if (m_state == WorkerUnitState.BUILD_LUMBERMILL
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {

			this.buildBuilding(UnitType.HUMAN_ELVEN_LUMBER_MILL);
		}

		else if (m_state == WorkerUnitState.BUILD_BLACKSMITH
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {

			this.buildBuilding(UnitType.HUMAN_BLACKSMITH);
		}

		else if (m_state == WorkerUnitState.BUILD_TOWER
				&& (unit.getStatus()[0] == 0 || unit.getStatus()[0] == 2)) {

			this.buildBuilding(UnitType.HUMAN_WATCH_TOWER);
		}
		
		this.previous_state_int = unit.getStatus()[0];
	}

	public void buildBuilding(UnitType building) {
		if (proxyBot.getGold() < building.getGoldCost()
				|| proxyBot.getWood() < building.getWoodCost()) {
			m_state = WorkerUnitState.IDLE;
		} else {
			if (pheromoneMap.getMagnitude(unit.getLocX(), unit.getLocY(),
					PheromoneType.GO_AWAY) >= GO_AWAY_LIMIT) {
				moveTrail(PheromoneType.GO_AWAY, PheromoneType.ENEMY);//moveTrail(PheromoneType.GO_AWAY);
			}

			// Else, move randomly
			else {
				if (proxyBot.canBuild(unit.getLocX(), unit.getLocY(), building)) {
					// System.out.println("WorkerUnit-Farm: Build Farm");
					//m_state = WorkerUnitState.BUILDING;
					proxyBot.build(unit.getUnitID(), 0, 0, true, building.getUnitTypeNum());

					// WargusUnit.setOnFarm(false);
					
					/*try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {

					}*/
				}

				else {
					moveRandom();
				}
			}
		}
	}

	public void buildState() {
		int increaseResourceLimit = 1000;
		
		double wood_mag = pheromoneMap.getMagnitude(unit.getLocX(), unit
				.getLocY(), PheromoneType.NEED_WOOD);
		double gold_mag = pheromoneMap.getMagnitude(unit.getLocX(), unit
				.getLocY(), PheromoneType.NEED_GOLD);
		double farm_mag = pheromoneMap.getMagnitude(unit.getLocX(), unit
				.getLocY(), PheromoneType.NEED_FARM);
		double barrack_mag = pheromoneMap.getMagnitude(unit.getLocX(), unit
				.getLocY(), PheromoneType.NEED_BARRACKS);
		double blacksmith_mag = pheromoneMap.getMagnitude(unit.getLocX(), unit
				.getLocY(), PheromoneType.NEED_BLACKSMITH);
		double lumbermill_mag = pheromoneMap.getMagnitude(unit.getLocX(), unit
				.getLocY(), PheromoneType.NEED_LUMBERMILL);
		double tower_mag = pheromoneMap.getMagnitude(unit.getLocX(), unit
				.getLocY(), PheromoneType.NEED_TOWER);

		double total_mag = wood_mag + gold_mag + farm_mag + barrack_mag
		+ blacksmith_mag + lumbermill_mag + tower_mag;

		double wood_prob = wood_mag / total_mag;
		double gold_prob = gold_mag / total_mag;
		double farm_prob = farm_mag / total_mag;
		double barracks_prob = barrack_mag / total_mag;
		double blacksmith_prob = blacksmith_mag / total_mag;
		double lumbermill_prob = lumbermill_mag / total_mag;
		double tower_prob = tower_mag / total_mag;
		
		
		System.out.println("Mags:");
		System.out.println("\tFind Wood: " + wood_mag);
		System.out.println("\tFind Gold: " + gold_mag);
		System.out.println("\tBuild Farm: " + farm_mag);
		System.out.println("\tBuild Barracks: " + barrack_mag);
		System.out.println("\tBuild Blacksmith: " + blacksmith_mag);
		System.out.println("\tBuild Lumbermill: " + lumbermill_mag);
		System.out.println("\tBuild Tower: " + tower_mag);
		

		double woodMax = wood_prob;
		double goldMax = woodMax + gold_prob;
		double farmMax = goldMax + farm_prob;
		double barracksMax = farmMax + barracks_prob;
		double blacksmithMax = barracksMax + blacksmith_prob;
		double lumbermillMax = blacksmithMax + lumbermill_prob;
		double towerMax = lumbermillMax + tower_prob;

		if (total_mag > 0) {
			
			double new_status = PheromoneMain.m_gen.nextDouble();
			System.out.println("Dice Roll: " + new_status);
			
			if (new_status < woodMax) {
				m_state = WorkerUnitState.FIND_WOOD;
				System.out.println("Find Wood Range: " + 0 + " - " + woodMax);

			} else if (new_status < goldMax && new_status >= woodMax) {
				m_state = WorkerUnitState.FIND_GOLD;
				System.out.println("Find Gold Range: " + woodMax + " - " + goldMax);

			} else if (new_status < farmMax && new_status >= goldMax
					&& proxyBot.getGold() > (UnitType.HUMAN_FARM.getGoldCost() + increaseResourceLimit)
					&& proxyBot.getWood() > (UnitType.HUMAN_FARM.getWoodCost() + increaseResourceLimit)) {
				m_state = WorkerUnitState.BUILD_FARM;
				System.out.println("Build Farm Range: " + goldMax + " - " + farmMax);

			} else if (new_status < barracksMax
					&& proxyBot.getGold() > (UnitType.HUMAN_BARRACKS.getGoldCost())// + increaseResourceLimit)
					&& new_status >= farmMax
					&& proxyBot.getWood() > (UnitType.HUMAN_BARRACKS.getWoodCost())){// + increaseResourceLimit)) {
				m_state = WorkerUnitState.BUILD_BARRACKS;
				System.out.println("Build Barracks Range: " + farmMax + " - " + barracksMax);

			} else if (new_status < blacksmithMax
					&& new_status >= barracksMax
					&& proxyBot.getGold() > (UnitType.HUMAN_BLACKSMITH.getGoldCost() + increaseResourceLimit)
					&& proxyBot.getWood() > (UnitType.HUMAN_BLACKSMITH.getWoodCost() + increaseResourceLimit)) {
				m_state = WorkerUnitState.BUILD_BLACKSMITH;
				System.out.println("Build Blacksmith Range: " + barracksMax + " - " + blacksmithMax);

			} else if (new_status < lumbermillMax
					&& proxyBot.getGold() > (UnitType.HUMAN_ELVEN_LUMBER_MILL.getGoldCost() + increaseResourceLimit)
					&& new_status >= blacksmithMax
					&& proxyBot.getWood() > (UnitType.HUMAN_ELVEN_LUMBER_MILL.getWoodCost() + increaseResourceLimit)) {

				m_state = WorkerUnitState.BUILD_LUMBERMILL;
				System.out.println("Build Lumbermill Range: " + blacksmithMax + " - " + lumbermillMax);
			} else if (new_status > lumbermillMax
					&& proxyBot.getGold() > (UnitType.HUMAN_WATCH_TOWER.getGoldCost() + increaseResourceLimit)
					&& proxyBot.getWood() > (UnitType.HUMAN_WATCH_TOWER.getWoodCost()  + increaseResourceLimit)) {

				m_state = WorkerUnitState.BUILD_TOWER;
				System.out.println("Build Tower Range: " + lumbermillMax + " - " + towerMax);

			} else {

				if (proxyBot.getGold() < 1000)
					m_state = WorkerUnitState.FIND_GOLD;
				else if (proxyBot.getWood() < 1000)
					m_state = WorkerUnitState.FIND_WOOD;
				else
				{
					if(proxyBot.getGold() < proxyBot.getWood())
						m_state = WorkerUnitState.FIND_GOLD;
					else
						m_state = WorkerUnitState.FIND_WOOD;
				}
			}

		}

		else {

			if(proxyBot.getGold() < proxyBot.getWood())
				m_state = WorkerUnitState.FIND_GOLD;
			else
				m_state = WorkerUnitState.FIND_WOOD;
		}

	}

}